package com.juma.cartridge.rlock.aop;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtils;

/**
 * 注解中的key表达式解析工具类
 * @ClassName KeyParseUtils
 * @Description
 * @Author zhuangguangyou
 * @Date 2019年10月11日 下午4:43:06
 * @Version 1.0
 *
 */

public class KeyParseUtils {

    /**
     * 解析注解中的key表达式,将其转化为具体的值
     * @param keyExp key表达式
     * @param args AOP调用方法的原始参数
     * @return
     */
    public static String parse(String keyExp,Object[] args) {
        
        Pattern p = Pattern.compile("\\#\\{.+}");
        Matcher m = p.matcher(keyExp);
        if(!m.find()) {
            return keyExp;
        }
        
        
        //解析key中包含的表达式
        Map<String,String> kv = new HashMap<String,String>();
        for (int i=0;i<keyExp.length();) {
            char c = keyExp.charAt(i);
            if(c!='#') {
                i++;
                continue;
            }
            if(keyExp.charAt(i+1)!='{') {
                i++;
                continue;
            }
            int blockEnd = keyExp.indexOf('}', i)+1;
            if(blockEnd==0) {
                throw new IllegalArgumentException(keyExp);
            }
            String k = keyExp.substring(i, blockEnd);
            String v = k.replace("#{", "").replace("}", "");
            if(!Pattern.compile("^(p\\d+)|(p\\d+\\.\\w+)$").matcher(v).find()) {
                throw new IllegalArgumentException(keyExp);
            }
            kv.put(k, v);
            i=blockEnd+1;
        }
        
        //解析表达式值
        String retValue = keyExp;
        try {
            for(Entry<String,String> entry:kv.entrySet()) {
                String[] vs = entry.getValue().split("\\.");
                int idx = Integer.parseInt(vs[0].substring(1));
                Object obj = args[idx];
                if(vs.length>1) {
                    String nv = BeanUtils.getProperty(obj, vs[1]);
                    retValue = retValue.replace(entry.getKey(), nv);
                } else {
                    retValue = retValue.replace(entry.getKey(), String.valueOf(obj));
                }
            }
        }catch(Exception e) {
            throw new IllegalArgumentException(keyExp,e);
        }
        
        return retValue;
    }
    
}
